<?php
require_once 'Doctrine/Common/ClassLoader.php';
use Doctrine\Common\ClassLoader;

class App_Plugin_ModuleLoader extends Zend_Controller_Plugin_Abstract{

    /**
     * @var string
     */
    private $_moduleName = null;

    /**
     * @var string
     */
    private $_modulePath = null;

    /**
     * @var Zend_Controller_Router_Rewrite
     */
    private $_router = null;

    /**
     * @var Zend_Config
     */
    private $_currentConfig = null;
    /**
     * @var Zend_Application
     */
    private $_application = null;

    /**
     * @var Zend_Controller_Dispatcher_Interface
     */
    private $_dispatcher = null;

    /**
     * @var Zend_Controller_Front
     */
    private $_frontController = null;

    public function routeStartup(Zend_Controller_Request_Abstract $request){
        $frontController = Zend_Controller_Front::getInstance();
        $this->setFrontController($frontController);
        $this->setDispatcher($frontController->getDispatcher());
        $this->setCurrentConfig(Zend_Registry::get('config'));
        $this->setApplication(Zend_Registry::get('application'));
    }

    /**
     * Main plugin body
     * 
     * @param Zend_Controller_Request_Abstract $request
     * @return void
     */
    public function routeShutdown(Zend_Controller_Request_Abstract $request){
        $frontController = $this->getFrontController();
        
        $this->setModuleName($request->getModuleName());
        $this->setModulePath($frontController->getModuleDirectory($this->getModuleName()));
        $this->setRouter($frontController->getRouter());

        $this->_initConfig();
    }

    /**
     * Module config initializer
     * @return void
     */
    private function _initConfig(){
        $config = new Zend_Config_Ini($this->getModulePath() . '/configs/module.ini', APPLICATION_ENV, true);
        // Writing module config to application config
        $this->getCurrentConfig()->merge($config);

        // Writing summary config to application config
        $this->getApplication()->setOptions($this->getCurrentConfig()->toArray());

        // Close config for modifications
        $this->getCurrentConfig()->setReadOnly();

        $this->_initResources($config);
    }

    /**
     * Module resource loader
     * 
     * @param  $config
     * @return void
     */
    private function _initResources($config){
        if(empty($config))
            return;

        $config = $config->toArray();
        if(!isset($config['resources']['autoloader']['namespaces']))return;
        foreach($config['resources']['autoloader']['namespaces'] as $namespace=>$path){
	        $classLoader = new ClassLoader($namespace, $path);
	        $classLoader->register();
    	}
    }

    /**
     * @param  string $moduleName
     * @return void
     */
    public function setModuleName($moduleName) {
        $this->_moduleName = (string) $moduleName;
    }

    /**
     * @return string
     */
    public function getModuleName() {
        return $this->_moduleName;
    }

    /**
     * @param  string $modulePath
     * @return void
     */
    public function setModulePath($modulePath) {
        $this->_modulePath = (string) $modulePath;
    }

    /**
     * @return string
     */
    public function getModulePath() {
        return $this->_modulePath;
    }

    /**
     * @param Zend_Application $application
     * @return void
     */
    public function setApplication($application) {
        $this->_application = $application;
    }

    /**
     * @return Zend_Application
     */
    public function getApplication() {
        return $this->_application;
    }

    /**
     * @param  Zend_Config $currentConfig
     * @return void
     */
    public function setCurrentConfig($currentConfig) {
        $this->_currentConfig = $currentConfig;
    }

    /**
     * @return Zend_Config
     */
    public function getCurrentConfig() {
        return $this->_currentConfig;
    }

    /**
     * @param  Zend_Controller_Router_Rewrite $router
     * @return void
     */
    public function setRouter($router) {
        $this->_router = $router;
    }

    /**
     * @return Zend_Controller_Router_Rewrite
     */
    public function getRouter() {
        return $this->_router;
    }

    public function setDispatcher($dispatcher) {
        $this->_dispatcher = $dispatcher;
    }

    public function getDispatcher() {
        return $this->_dispatcher;
    }

    public function setFrontController($frontController) {
        $this->_frontController = $frontController;
    }

    public function getFrontController() {
        return $this->_frontController;
    }
}